package test_pkg

import (
	"fmt"
	"time"
)

// 通常使用这样的格式来声明通道：var identifier chan datatype
// 未初始化的通道的值是 nil。 所以通道只能传输一种类型的数据，比如 chan int 或者 chan string，
// 所有的类型都可以用于通道，空接口 interface{} 也可以。甚至可以（有时非常有用）创建通道的通道
func sendData(ch chan int) {
	for i := 0; ; i++ {
		ch <- i
	}
}

func getData(ch chan int) {
	var input int
	//为通道解除阻塞，无限循环读取
	for {
		input = <-ch
		fmt.Printf("input: %v\n", input)
	}
}

func Test_chan() {
	// var ch chan int
	// ch = make(chan int])	//无缓冲通道
	// ch = make(chan int， [len])	//缓冲通道 len 通道的容量

	// ch := make(chan int)
	ch := make(chan int, 10000)
	//不要使用打印状态来表明通道的发送和接收顺序：由于打印状态和通道实际发生读写的时间延迟会导致和真实发生的顺序不同
	//对于同一个通道，发送操作在接受者准备好之前是阻塞的 如果 ch 中的数据无人接收，就无法再给通道传入数据
	//对于同一个通道，接受者也是阻塞的，直到发送者准备好（发送者在发送数据或者通道是满载的），如果通道中没有数据，接受者就阻塞了
	// 同步：ch :=make(chan type, value)
	// value == 0 -> synchronous, unbuffered (阻塞）
	// value > 0 -> asynchronous, buffered（非阻塞）取决于 value 元素
	go sendData(ch)
	go getData(ch)
	// fmt.Println(<-ch) //如果没有接受者 getdata 就只能输出 1
	//等待 1s 协程完成后再退出
	time.Sleep(1 * time.Second)
}
  